package com.gitee.wsl.coroutines.job

import com.gitee.wsl.coroutines.job.sheduler.IScheduler
import kotlin.jvm.Transient
import kotlin.reflect.KClass

class JobDetail(
    var name: String? = null,
    private var m_sGroup: String = IScheduler.DEFAULT_GROUP,
    var isDurable: Boolean = false,
    var description: String? = null,
    var shouldRecover: Boolean = false,
    var jobClass: KClass<out IJob>?=null,
    var jobDataMap: JobDataMap=JobDataMap(),
) {

    var group: String?
        /**
         * Get the group of this `Job`.
         */
        get() = m_sGroup
        /**
         *
         *
         * Set the group of this `Job`.
         *
         *
         * @param group
         * if `null`, Scheduler.DEFAULT_GROUP will be used.
         * @exception IllegalArgumentException
         * if the group is an empty string.
         */
        set(group) {
            //if (group != null)
                //ValueEnforcer.isFalse(group.trim { it <= ' ' }.isEmpty(), "Group name cannot be empty.")
            if (group == null)
                m_sGroup = IScheduler.DEFAULT_GROUP
            else
                m_sGroup = group
            m_aKey = null
        }

   
    val fullName: String
        /**
         * Returns the 'full name' of the `JobDetail` in the format
         * "group.name".
         */
        get() = "$m_sGroup.$name"


    @Transient
    private var m_aKey: JobKey? = null
    
    var key: JobKey?
        get() {
            if (m_aKey == null) {
                if (name == null) return null
                m_aKey = JobKey(name!!, group)
            }
            return m_aKey
        }
        set(key) {
            name = key!!.name
            group = key.group
            m_aKey = key
        }

    /**
     * Set whether or not the the `Scheduler` should re-execute the
     * `Job` if a 'recovery' or 'fail-over' situation is
     * encountered.<br></br>
     * If not explicitly set, the default value is `false`.
     *
     * @see com.helger.quartz.IJobExecutionContext.isRecovering
     */

    val isPersistJobDataAfterExecution: Boolean
        /**
         * @return whether the associated Job class carries the
         * [PersistJobDataAfterExecution] annotation.
         */
        get() = true

    val isConcurrentExectionDisallowed: Boolean
        /**
         * @return whether the associated Job class carries the
         * [DisallowConcurrentExecution] annotation.
         */
        get() = true


    /**
     *
     *
     * Return a simple string representation of this object.
     *
     */
    override fun toString(): String {
        return ("JobDetail '" +
                fullName +
                "':  jobClass: '" +
                (jobClass?.simpleName) +
                " concurrentExectionDisallowed: " +
                isConcurrentExectionDisallowed +
                " persistJobDataAfterExecution: " +
                isPersistJobDataAfterExecution +
                " isDurable: " +
                isDurable +
                " requestsRecovers: " +
                shouldRecover)
    }

    val jobBuilder: JobBuilder
        get() = JobBuilder.newJob()
            .ofType(jobClass!!)
            .requestRecovery(shouldRecover)
            .storeDurably(isDurable)
            .usingJobData(jobDataMap)
            .withDescription(description?:"")
            .withIdentity(key!!)


    companion object {
        fun create(name: String, group: String?, jobClass: KClass<out IJob>): JobDetail {
            val ret = JobDetail(jobClass = jobClass)
            ret.name = name
            ret.group = group
            return ret
        }
    }
}